package com.chinaunicom.emergency.action;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chinaunicom.emergency.annotation.Permission;
import com.chinaunicom.emergency.model.Role;
import com.chinaunicom.emergency.model.YjglOrg;
import com.chinaunicom.emergency.service.RoleService;
import com.chinaunicom.emergency.util.Assert;
import com.chinaunicom.emergency.util.UpdateUtil;
import com.chinaunicom.emergency.exception.CheckException;
import com.chinaunicom.emergency.repository.RolePermissionsRepository;
import com.chinaunicom.emergency.repository.RoleRepository;
import com.chinaunicom.emergency.repository.UserRoleRepository;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @Author liliang
 * @Date 2019/12/18 15:22
 * @Version 1.0
 */
@RestController
@Api(tags = {"角色管理"})
@RequestMapping("/api/role")
@Log4j2
@RefreshScope
public class RoleAction extends BaseAction {
    @Autowired
    RoleRepository roleRepository;
    @Autowired
    UserRoleRepository userRoleRepository;
    @Autowired
    RolePermissionsRepository rolePermissionsRepository;
    @Autowired
    RoleService roleService;


    @ApiOperation("角色新增")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = "token", required = true, dataType = "String", paramType = "header")
    })
    @Permission("role:add")
    @PostMapping(value = "/add")
    public Object add(@RequestBody Role role) throws CheckException {
        Assert.isBlank(role.getRoleName(), "角色名称不能为空");
        Assert.isBlank(role.getRoleCode(), "角色编码不能为空");
        Role existByCode = roleRepository.findByRoleCodeAndIsSoftDel(role.getRoleCode(),0);
        Assert.isNotNull(existByCode,"角色编码重复,请勿重复创建");

        role.setIsSoftDel(0);
        role.setCreateBy(getCurrUserId());
        role.setCreateTime(new Date());
        roleRepository.save(role);
        return success();
    }

    @ApiOperation("角色修改")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = "token", required = true, dataType = "String", paramType = "header")
    })
    @Permission("role:update")
    @PutMapping(value = "/update")
    public Object update(@RequestBody Role role) throws CheckException {
        Assert.isBlank(role.getRoleName(), "角色名称不能为空");
        Assert.isBlank(role.getRoleCode(), "角色编码不能为空");
        Assert.isBlank(role.getPid(), "角色id不能为空");
        Role oldRole = roleRepository.findByPidAndIsSoftDel(role.getPid(),0);
        Assert.isNull(oldRole,"该角色不存在,修改失败");
        Assert.isNotEquals(role.getRoleCode(),oldRole.getRoleCode(),"角色编码无法修改,请重新填写!");

        role.setUpdateBy(getCurrUserId());
        role.setUpdateTime(new Date());
        UpdateUtil.copyNullProperties(oldRole,role);
        roleRepository.save(role);
        return success();
    }

    @ApiOperation("角色删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = "token", required = true, dataType = "String", paramType = "header")
    })
    @Permission("role:delete")
    @DeleteMapping(value = "/delete")
    public Object delete(@RequestParam(value = "pid") String pid) throws CheckException {
        Assert.isBlank(pid, "角色id不能为空");
        Role role = roleRepository.findByPidAndIsSoftDel(pid,0);
        Assert.isNull(role,"该角色不存在,删除失败");
        //角色是否被关联用户
        List<String> userNameList = userRoleRepository.findUserNameByRoleId(pid);
        Assert.isNotNull(userNameList,"该角色已关联用户,无法删除");

        role.setDeleteBy(getCurrUserId());
        role.setIsSoftDel(1);
        role.setDeleteTime(new Date());
        roleService.delete(role);
        return success();
    }

    @ApiOperation("单个角色明细查看")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = "token", required = true, dataType = "String", paramType = "header")
    })
    @Permission("role:detail")
    @GetMapping(value = "/{pid}")
    public Object findByPid(@PathVariable String pid) throws CheckException {
        Assert.isBlank(pid, "角色id不能为空");
        Role role = roleRepository.findByPidAndIsSoftDel(pid,0);
        return success(role);
    }

    @ApiOperation("分页查看角色列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorization", value = "token", required = true, dataType = "String", paramType = "header")
    })
    @Permission("role:page")
    @GetMapping(value = "/page")
    public Object findPage(@RequestParam(value = "limit", required = false) Integer limit,
                           @RequestParam(value = "page", required = false) Integer page,
                           @RequestParam(value = "roleName", required = false) String roleName
    ) throws CheckException {
        Map<String, Object> para = new HashMap<>();
        para.put("limit", limit == null ? 10 : limit);
        para.put("page", page == null ? 1 : page);
        para.put("isSoftDel", 0);
        para.put("roleName",roleName);
        Sort sort = Sort.by(Sort.Direction.ASC, "createTime");
        Page<YjglOrg> pages = roleRepository.findAll(roleService.findPageByCondition(para), getPageable(para, sort));

        return page(pages);
    }


    @ApiOperation("角色设置资源关系")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "token", required = true, paramType = "header", dataType = "String")
    })
    @Permission("role:setPermission")
    @PostMapping(value = "/rolePer")
    public Object setRolePermission(@RequestParam String roleId,
                                    @RequestBody List<String> permissionList) throws Exception {
        Assert.isBlank(roleId,"角色id不能为空");
        Role role = roleRepository.findByPidAndIsSoftDel(roleId,0);
        Assert.isNull(role,"该角色不存在,无法关联权限");
        List<String> roleIdList = Lists.newArrayList();
        roleIdList.add(roleId);
        List<String> oldPerList = rolePermissionsRepository.findPermissionByRoleId(roleIdList);
        if(CollectionUtils.isEmpty(oldPerList) && CollectionUtils.isEmpty(permissionList)){
            return success();
        }
        if(!CollectionUtils.isEmpty(oldPerList) && !CollectionUtils.isEmpty(permissionList)){
            if(oldPerList.containsAll(permissionList) && permissionList.containsAll(permissionList)){
                return success();
            }
        }

        roleService.setPermission(roleId, permissionList, getCurrUserId());
        return success();
    }


    @ApiOperation("角色资源关系获取")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "token", required = true, paramType = "header", dataType = "String")
    })
    @Permission("role:getPermission")
    @GetMapping(value = "/rolePer/list")
    public Object getRolePermission(@RequestParam String roleId) {
        List<String> roleIds = Arrays.asList(roleId.split(","));
        List<Object[]> objs = rolePermissionsRepository.findPermissionByRoleId(roleIds);
        JSONArray array = new JSONArray();
        for (Object[] obj : objs) {
            JSONObject rolePer = new JSONObject();
            rolePer.put("roleId", roleId);
            rolePer.put("permissionsId", obj[1]);
            array.add(rolePer);
        }
        return success(array);
    }


    @ApiOperation("获取所有角色列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "token", required = true, paramType = "header", dataType = "String")
    })
    @Permission("role:all")
    @GetMapping(value = "/allList")
    public Object getOrgAll() throws CheckException {
        List<Role> roleList = roleRepository.findAllByIsSoftDel(0);
        
        return success(roleList);
    }


}
